"""
FIVEDASH(TM) -- General Purpose Accounting Software
Copyright (C) 2008  Obol Software Pty Ltd

This program is free software: you can redistribute it and/or modify
it. For terms and conditions, see fivedash/license/license.txt

"""

from mod_python import apache
from mod_python import Session
from mod_python import util

from phunc import *
from phunc.cx_wrapper import db_tools
from phunc.form import user_form
from phunc.logger import logger

# legacy namespacing
GeneralBusinessErr = exception.GeneralBusinessErr
qtable = table.qtable

def index(req, **params):
	"""displays user list"""
	page = Page(req, app_db=True)
	if not page.session.has_key('login_company'):
		raise GeneralBusinessErr('can not connect to company database!')
	broadcast_message = params.has_key('broadcast_message') and params['broadcast_message'] or ''
	sql_str = "SELECT a.*, b.name AS user_name, c.name AS group_name FROM system.affiliation a, system.user b, system.group c WHERE a.user_id=b.id AND a.group_id=c.id AND a.company_id=%s ORDER BY a.user_id" % page.session['login_company']
	page_split_setup={
		'cursor':page.app_db.cursor(),
		'sql':sql_str,
		'skin':page.session['skin'],
		'page':params.has_key('page') and params['page'] and int(params['page']) or 1,
		'pagesize':8,
		'url':"/bin/admin.py",
		'params':{}
	}
	users = table.ControlPage(**page_split_setup)
	page.content = {
		'user_list':users.result,
		'page_split':users.createHtml(),
		'query_string':info.query_string.replace('?', '&amp;')
	}
	page.setup = {
		'breadcrumbs':['Admin'],
		'menu_title':'Admin Portal',
		'menu':['newuser','newsalesagent','newtax','smtpset'],
		'content_title':'Users',
		'broadcast_message':broadcast_message,
		'template':'admin/a.opt',
        'javascript':True
	}
	page.info = {
		'query_string':info.query_string,
	}
	return page.render(debug=True)

#TODO:is system.role in bde database useful?
def create_user_page(req, **params):
	"""displays user list and form to create a new user"""
	page = Page(req, app_db=True)
	group_list = db_tools.exec_action(page.app_db.cursor(),'get_group')
	page.content = {
		'group_list':group_list
	}
	page.setup = {
		'breadcrumbs':['admin','New User'],
		'menu_title':'Admin Portal',
		'menu':['newuser!','newsalesagent','newtax','smtpset'],
		'content_title':'New User',
		'broadcast_message':params.has_key('broadcast_message') and params['broadcast_message'] or None,
		'template':'admin/auc.opt',
		'form':True
	}
	page.info = {
		'query_string':info.query_string
	}
	return page.render()

def create_user(req,**params):
	"""actually creates a new user -- redirects to index page"""
	try:
		session = Session.Session(req)
		check_access(req,session, req.uri)
		app_db = get_app_connection()
		broadcast_message = 'An error occurred. The user was not created'
		if not session.has_key('login_company'):
			raise GeneralBusinessErr('Cannot connect to company database')
		else:
			from phunc import user
			user_id, create_message = user.createUser(app_db, params['name'], params['password'])
			grant_message = user.grantUser(app_db, user_id, int(session['login_company']), int(params['group_id']))
			app_db.commit()
			broadcast_message = create_message + grant_message
	except GeneralBusinessErr,e:
		broadcast_message = e.getErrMsg()
	except Exception,e: 
		errmsg = "%s" % e.__str__ + ' : ' + ','.join([str(arg) for arg in e.args])
		broadcast_message = errmsg.replace('<','').replace('>','').replace('.__str__','')
	except:
		broadcast_message = 'An undefined error occurred'
	finally:
		util.redirect(req,"/bin/admin.py?broadcast_message=%s"%broadcast_message)

def delete_user(req, **params):
	"""actually deletes a user -- redirects to index page"""
	try:
		session = Session.Session(req)
		check_access(req,session, req.uri)
		app_db = get_app_connection()
		dbc = app_db.cursor()
		broadcast_message = "An error occurred"
		if not utils.is_root_user(params['user_id'], dbc):	
			db_tools.exec_action(dbc, 'delete_user', [params['user_id']])
			db_tools.exec_action(dbc, 'remove_right_on_user', [params['user_id']])
			app_db.commit()
			broadcast_message="User '%s' removed" % params['user_name']
		else:
			broadcast_message = "Superusers can't be deleted from within this portal"
	except GeneralBusinessErr,e:
		broadcast_message = e.getErrMsg()
	except Exception,e: 
		errmsg = "%s" % e.__str__ + ' : ' + ','.join([str(arg) for arg in e.args])
		broadcast_message = errmsg.replace('<','').replace('>','').replace('.__str__','')
	except:
		broadcast_message = 'An undefined error occurred'
	finally:
		util.redirect(req,"/bin/admin.py?broadcast_message=%s" % broadcast_message)	    
	
def edit_user_page(req, **params):
	"""displays a form for editing basic user details"""
	page = Page(req, app_db=True)
	group_list = db_tools.exec_action(page.app_db.cursor(),'get_group')
	page.content = {
		'group_list':group_list,
		'user_name':params['user_name'],
		'user_id':params['user_id'],
		'group_id':params['user_group'],
		'company_id':params['user_company']
	}
	page.setup = {
		'breadcrumbs':['admin', 'Edit User - ' + params['user_name']],
		'menu_title':'Admin Portal',
		'menu':['newuser','newsalesagent','newtax','smtpset'],
		'content_title':params['user_name'],
		'broadcast_message':params.has_key('broadcast_message') and params['broadcast_message'] or None,
		'template':'admin/aue.opt',
		'form':True
	}
	page.info = {
		'query_string':info.query_string,
	}
	return page.render()

def edit_user(req, **params):
	"""actually updates the user -- redirects to index page"""
	try:
		session = Session.Session(req)
		check_access(req,session, req.uri)
		app_db = get_app_connection()
		if params.has_key('user_id'):
			db_tools.exec_action(app_db.cursor(),'edit_user_group',[params['group_id'],params['user_id'],params['company_id'],params['old_group_id']])
			app_db.commit()
			broadcast_message = 'User updated'
			if int(session['login_user_id'])==int(params['user_id']):
				session['login_group'] = params['group_id']
				session.save()
	except GeneralBusinessErr,e:
		broadcast_message = e.getErrMsg()
	except Exception,e: 
		errmsg = "%s" % e.__str__ + ' : ' + ','.join([str(arg) for arg in e.args])
		broadcast_message = errmsg.replace('<','').replace('>','').replace('.__str__','')
	except:
		broadcast_message = 'An undefined error occurred'
	finally:
		util.redirect(req,"/bin/admin.py?broadcast_message=%s" % broadcast_message)

def show_tables(req, **params):
	"""DEPRECATED -- display a list of tables, with links to drill into them"""
	from phunc.table import qtable
	page = Page(req, company_db=True)
	page.content = {
		'qtable':qtable(company_db, 'SELECT * FROM ' + info.t + ' ORDER BY id' + info.page_string, '/bin/admin.py/show_tables?t=' + info.t + info.query_string.replace('?', '&amp;'), info.page)
	}
	page.setup = {
		'breadcrumbs':['admin','Raw Table Display - ' + info.t],
		'menu_title':'Admin Portal',
		'menu':['newuser','newsalesagent','newtax','smtpset'],
		'content_title':info.t,
		'template':'admin/at.opt'
	}
	page.info = {
	  	'query_string':info.query_string,
		't':info.t
	}
	return page.render()
				
def show_views(req, **params):
	"""DEPRECATED -- display a list of views, with links to drill into them"""
	from phunc.table import qtable
	page = Page(req, company_db=True)
	page.content = {
		'qtable':qtable(company_db, 'SELECT * FROM ' + info.v + info.page_string, '/bin/admin.py/show_views?v=' + info.v + info.query_string.replace('?', '&amp;'), info.page )
	}
	page.setup = {
		'breadcrumbs':['admin','Public View - ' + info.v],
		'menu_title':'Admin Portal',
		'menu':['newuser','newsalesagent','newtax','smtpset'],
		'content_title':info.v,
		'template':'admin/av.opt'
	}
	page.info = {
		'query_string':info.query_string,
		'v':info.v
	}
	return page.render()

def create_sales_agent_page(req, **params):
	"""display first of 2 forms for creating a new sales agent"""
	page = Page(req, company_db=True)
	page.content = {
		'entitytypes':db_tools.exec_action(page.company_db.cursor(),'get_entity_types')
	}
	page.setup = {
		'breadcrumbs':['admin', 'New Sales Agent'],
		'menu_title':'Admin Portal',
		'menu':['newuser','newsalesagent!','newtax','smtpset'],
		'content_title':'New Sales Agent',
		'template':'admin/aca.opt'
		}
	page.info = {
		'query_string':info.query_string,
	}
	return page.render()

def create_sales_agent_details(req, **params):
	"""display second of 2 forms for creating a new sales agent"""
	page = Page(req, company_db=True)
	page.content = {
		'lcase_entity_type':params['entity_type'].capitalize(),
		'entities':db_tools.exec_action(page.company_db.cursor(),'get_all_entities_not_sales_agent', [params['entity_type']])
	}
	if len(page.content['entities']) == 0:
		util.redirect(req,"/bin/admin.py?broadcast_message=%s" % ('No %s entities available' % params['entity_type']))
	page.setup = {
		'breadcrumbs':['admin', 'New Sales Agent'],
		'menu_title':'Admin Portal',
		'menu':['newuser','newsalesagent!','newtax','smtpset'],
		'content_title':'New Sales Agent',
		'template':'admin/aca2.opt'
	}
	page.info = {
		'query_string':info.query_string
	}
	return page.render()
	
def create_sales_agent(req, **params):
	"""actually creates a sales agent -- redirects to index page"""
	try:
		session = Session.Session(req)
		check_access(req,session, req.uri)
		company_db = get_connection(session)
		if(params['entity_id'] == '' or params['commission'] == ''):
			broadcast_message = 'Wrong parameters!'
		else:
			db_tools.exec_action(company_db.cursor(),'insert_sales_agent', [int(params['entity_id']), int(params['commission'])])
			company_db.commit()
			broadcast_message = 'Sales agent created'
	except GeneralBusinessErr,e:
		broadcast_message = e.getErrMsg()
	except Exception,e: 
		errmsg = "%s" % e.__str__ + ' : ' + ','.join([str(arg) for arg in e.args])
		broadcast_message = errmsg.replace('<','').replace('>','').replace('.__str__','')
	except:
		broadcast_message = 'An undefined error occurred'
	finally:
		util.redirect(req, '/bin/admin.py?broadcast_message=%s' % broadcast_message)

def send_email_page(req, **params):
	"""displays a form for generating a system email"""
	page = Page(req)
	page.setup = {
		'breadcrumbs':['admin', 'Message management'],
		'menu_title':'Admin Portal',
		'menu':['newuser','newsalesagent','newtax','smtpset'],
		'broadcast_message':params.has_key('broadcast_message') and params['broadcast_message'] or None,
		'content_title':'Create New Message',
		'template':'admin/email.opt',
		'form':True,
        'javascript':True
	}
	page.info = {
		'query_string':info.query_string,
	}
	return page.render()

def send_email(req, **params):
	"""actually sends a system email -- redirects to email form"""
	try:
		session = Session.Session(req)
		check_access(req,session, req.uri)
		from_email = params['from']
		to_email = params['to'].split(',')
		subject = params['subject']
		root_path = req.document_root()
		attach_length = int(params['attach_length'])
		file_path = []
		if attach_length>0:
			import os			
			for i in range(attach_length):
				if params.has_key('attach_file'+str(i+1)):
					filename = params['attach_file'+str(i+1)].filename
					filevalue = params['attach_file'+str(i+1)].file.read()
					filepath = os.path.join(root_path,filename)
					utils.save_upload_file(root_path, filepath, filevalue)
					file_path.append(filepath)
		email_content = params['content']
		if params.has_key('auth_required') and params['auth_required']:
			auth_required = 1
			smtp_server = params['smtp_server']
			smtp_user = params['smtp_user']
			smtp_pass = params['smtp_pass']			
			user_email.send_mail(send_from = from_email,send_to = to_email,subject = subject,text = email_content,files = file_path,server=smtp_server,auth_required = auth_required,smtp_user = smtp_user,smtp_pass = smtp_pass)
		else:
			user_email.send_mail(send_from = from_email,send_to = to_email,subject = subject,text = email_content,files = file_path)
		broadcast_message = "Email sent"
	except GeneralBusinessErr,e:
		broadcast_message = e.getErrMsg()
	except Exception,e: 
		errmsg = "%s" % e.__str__ + ' : ' + ','.join([str(arg) for arg in e.args])
		broadcast_message = errmsg.replace('<','').replace('>','').replace('.__str__','')
	except:
		broadcast_message = 'An undefined error occurred'
	finally:
		util.redirect(req,"/bin/admin.py/send_email_page?broadcast_message=%s"%broadcast_message)

def smtp_server_setting(req, **params):
	"""display a form for setting smtp server defaults"""
	page = Page(req)
	page.setup = {
		'breadcrumbs':['admin', 'Configure SMTP Settings'],
		'menu_title':'Admin Portal',
		'menu':['newuser','newsalesagent','newtax','smtpset!'],
		'broadcast_message':params.has_key('broadcast_message') and params['broadcast_message'] or None,
		'content_title':'Configure SMTP Settings',
		'template':'admin/smtp_set.opt',
		'form':True,
	}
	page.info = {
		'query_string':info.query_string
	}
	return page.render()

def set_smtp_server(req, **params):
	"""actually set the smpt server defaults -- redirects to set smtp server form"""
	try:
		session = Session.Session(req)
		check_access(req,session, req.uri)
		company_db = get_connection(session)
		dbc = company_db.cursor()
		for code_id in [info.THIS_EMAIL,info.SMTP_SERVER,info.SMTP_USER,info.SMTP_PASS]:
			code_value = db_tools.exec_action(dbc,'get_sys_code', [code_id])
			if not code_value:
				db_tools.exec_action(dbc,'insert_sys_code', [code_id,params[code_id],code_id])
			else:				
				db_tools.exec_action(dbc,'update_sys_code', [params[code_id],code_id,code_id])
		company_db.commit()
		broadcast_message = "SMTP server set"
	except GeneralBusinessErr,e:
		broadcast_message = e.getErrMsg()
	except Exception,e: 
		errmsg = "%s" % e.__str__ + ' : ' + ','.join([str(arg) for arg in e.args])
		broadcast_message = errmsg.replace('<','').replace('>','').replace('.__str__','')
	except:
		broadcast_message = 'An undefined error occurred'
	finally:
		util.redirect(req,"/bin/admin.py/smtp_server_setting?broadcast_message=%s"%broadcast_message)

def insert_transaction_tax(req, **params):
	"""displays a form for creating a transaction tax"""
	page = Page(req, company_db=True)
	dbc = page.company_db.cursor()
	dbc.execute('SELECT * FROM system.transaction_tax')
	page.content = {
		'has_taxes':dbc.rowcount > 0,
		'tax_list':utils.dictfetch(dbc),
		'default_tax_is_null':db_tools.exec_action(dbc, 'default_tax_is_null')[0]['bool']
	}
	page.setup = {
		'breadcrumbs':['admin','New Transaction Tax'],
		'menu_title':'Admin Portal',
		'menu':['newuser','newsalesagent','newtax!','smtpset'],
		'broadcast_message':params.has_key('broadcast_message') and params['broadcast_message'] or None,
		'content_title':'New Transaction Tax',
		'template':'admin/insert_tr_tax.opt',
		'form':True,
	}
	return page.render()

def create_transaction_tax(req, **params):
	"""actually creates a transaction tax -- redirects to transaction tax form"""
	try:
		session = Session.Session(req)
		check_access(req, session, req.uri)
		company_db = get_connection(session)
		dbc = company_db.cursor()
		dbc.execute('''
			INSERT INTO system.transaction_tax (shortname, name, tax_page_id, rate, included_in_unit_price_default, track_on_purchases)
				VALUES ('%s', '%s', 0, %s, '%s', '%s')
		''' % (
			params['shortname'],
			params['name'],
			params['rate'],
			params['default_included'],
			params['track_on_purchases']
		))
		if params.has_key('default_tax') and params['default_tax'] == 'yes':
			dbc.execute('''
				UPDATE system.sys_code
					SET code_value = '%s'
					WHERE code_id = 'default_tax'
			''' % (
				params['shortname']
			))
		company_db.commit()
		broadcast_message = 'Tax created'
	except GeneralBusinessErr,e:
		broadcast_message = e.getErrMsg()
	except Exception,e: 
		errmsg = "%s" % e.__str__ + ' : ' + ','.join([str(arg) for arg in e.args])
		broadcast_message = errmsg.replace('<','').replace('>','').replace('.__str__','')
	except:
		broadcast_message = 'An undefined error occurred'
	finally:
		util.redirect(req, '/bin/admin.py/insert_transaction_tax?broadcast_message=%s' % broadcast_message)

def additional_setup(req, **params):
	"""assesses company setup status, provides some useful links"""
	page = Page(req, company_db=True)
	dbc = page.company_db.cursor()
	page.content = {
		'taxes_required':False,
		'tax_page_updated':False,
		'special_accounts_required':False
	}
	# check for transaction taxes
	dbc.execute('SELECT * FROM system.transaction_tax')
	if dbc.rowcount == 0:
		page.content['taxes_required'] = True

	# check if tax page was updated
	if params.has_key('broadcast_message') and params['broadcast_message'].find('New') >= 0:
		page.content['tax_page_updated'] = True

	# check for special accounts
	special_params = [{'param_id':'special_ac_sales_rev','param_name':'Sales Revenue','param_desc':'Sales Revenue'},{'param_id':'special_ac_cash','param_name':'CASH','param_desc':'CASH'}]			
	special_params_len = len(special_params)
	exist_special_params_len = db_tools.exec_action(page.company_db.cursor(), 'exist_special_params_len', [tuple([a['param_id'] for a in special_params])])[0]['special_params_len']
	if special_params_len!=exist_special_params_len and 'finance' in page.session['user_access'].values():
		page.content['special_accounts_required'] = True
	page.setup = {
		'breadcrumbs':['admin','Additional Setup'],
		'menu_title':'Admin Portal',
		'menu':['newuser','newsalesagent','newtax','smtpset'],
		'broadcast_message':params.has_key('broadcast_message') and params['broadcast_message'] or None,
		'content_title':'Additional Setup',
		'template':'admin/additional_setup.opt'
	}
	return page.render()
